#include "TcpConnection.h"
#include "EventLoop.h"
#include <iostream>
#include <sstream>

using std::cout;
using std::endl;
using std::ostringstream;

TcpConnection::TcpConnection(int fd, EventLoop *loop)
    : _loop(loop), _sockIO(fd), _sock(fd), _localAddr(getLocalAddr()), _peerAddr(getPeerAddr()) {
}

TcpConnection::~TcpConnection() {
}

void TcpConnection::send(const string &msg) {
    _sockIO.writen(msg.c_str(), msg.size());
    // cout << "msg = " << msg << "\n";
    // cout << "send finished\n";
}

// 本函数的实现还是有点麻烦的？
// 需要将线程池中的线程处理好之后的msg发送给EventLoop
// 还需要将发送数据能力的函数send也发给EventLoop
// 还有发送数据的TcpConnection的对象都发给EventLoop
// 此处的对象就是隐含的this
void TcpConnection::sendInLoop(const string &msg) {
    if (_loop) {
        /* function<void()> f = bind(&TcpConnection::send, this, msg); */
        // void runInLoop(function<void()> &&)
        /* _loop->runInLoop(std::move(f)); */
        _loop->runInLoop(bind(&TcpConnection::send, this, msg));
    }
    std::cout << "信息发送成功\n";
}

string TcpConnection::receive() {
    char buff[65535] = {0};
    _sockIO.readLine(buff, sizeof(buff));

    return string(buff);
}

bool TcpConnection::isClosed() const {
    char buff[10] = {0};
    int ret = recv(_sock.fd(), buff, sizeof(buff), MSG_PEEK);
    return (0 == ret);
}

string TcpConnection::toString() {
    ostringstream oss;
    oss << _localAddr.ip() << ":"
        << _localAddr.port() << "---->"
        << _peerAddr.ip() << ":"
        << _peerAddr.port();

    return oss.str();
}

// 获取本端的网络地址信息
InetAddress TcpConnection::getLocalAddr() {
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr);
    // 获取本端地址的函数getsockname
    int ret = getsockname(_sock.fd(), (struct sockaddr *)&addr, &len);
    if (-1 == ret) {
        perror("getsockname");
    }

    return InetAddress(addr);
}

// 获取对端的网络地址信息
InetAddress TcpConnection::getPeerAddr() {
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr);
    // 获取对端地址的函数getpeername
    int ret = getpeername(_sock.fd(), (struct sockaddr *)&addr, &len);
    if (-1 == ret) {
        perror("getpeername");
    }

    return InetAddress(addr);
}

// 三个回调的注册
void TcpConnection::setNewConnectionCallback(const TcpConnectionCallback &cb) {
    _onNewConnection = cb;
}

void TcpConnection::setMessageCallback(const TcpConnectionCallback &cb) {
    _onMessage = cb;
}

void TcpConnection::setCloseCallback(const TcpConnectionCallback &cb) {
    _onClose = cb;
}

// 三个回调的执行
void TcpConnection::handleNewConnectionCallback() {
    if (_onNewConnection) {
        // using TcpConnectionPtr = shared_ptr<TcpConnection>;
        // using TcpConnectionCallback = function<void(const TcpConnectionPtr &)>
        /* _onNewConnection(shared_ptr<TcpConnection>(this)); */
        _onNewConnection(shared_from_this()); // 为了防止智能指针的误用
    } else {
        cout << "nullptr == _onNewConnection" << endl;
    }
}

void TcpConnection::handleMessageCallback() {
    if (_onMessage) {
        _onMessage(shared_from_this());
    } else {
        cout << "nullptr == _onMessage" << endl;
    }
}

void TcpConnection::handleCloseCallback() {
    if (_onClose) {
        _onClose(shared_from_this());
    } else {
        cout << "nullptr == _onClose" << endl;
    }
}
